home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / baspcx10.zip / BAS2PCX.C next >
C/C++ Source or Header  |  1991-03-09  |  8KB  |  397 lines

  1. /*
  2.  * Bas2PCX -- Convert a BASIC BLOAD image to .PCX format
  3.  *
  4.  * Usage:     bas2pcx <infile> [outfile]
  5.  *
  6.  * Where:     <infile>  = BLOAD image to load (.PIC extension default)
  7.  *            [outfile] = .PCX file generated.  If not specified
  8.  *                        input filename is used, with .PCX added.
  9.  */
  10.  
  11. /* INCLUDES */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <dos.h>
  17. #include <dir.h>
  18. #include <io.h>
  19. #include <alloc.h>
  20. #include <conio.h>
  21. #include <mem.h>
  22. #include <process.h>
  23.  
  24.  
  25.  
  26. /* DEFINES */
  27.  
  28. #define EGA_320_200_16    0x0D
  29.  
  30. #define graph_out(index, val)           \
  31.      {                              \
  32.      outp(0x3CE, index);            \
  33.      outp(0x3CF, val  );            \
  34.      }
  35.  
  36. #define seq_out(index, val)             \
  37.          {                              \
  38.          outp(0x3C4, index);            \
  39.          outp(0x3C5, val  );            \
  40.      }
  41.  
  42.  
  43.  
  44.  
  45. /* TYPEDEFS */
  46.  
  47. typedef unsigned char UBYTE;
  48. typedef int           WORD;
  49. typedef unsigned int  UWORD;
  50. typedef long          LONG;
  51. typedef unsigned long ULONG;
  52.  
  53.  
  54.  
  55.  
  56. /* FUNCTIONS */
  57.  
  58. /*
  59.  * get_parms() - Crack the parameters passed in from the command line.
  60.  */
  61. void get_parms(int argc, char *argv[], char *fin, char *fout)
  62. {
  63.  char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  64.  
  65.  
  66.  /* The first parameter is the input file.  Add .PIC extension if needed. */
  67.  
  68.  fnsplit(argv[1], drive, dir, file, ext);
  69.  
  70.  if(ext[0] == '\0')
  71.   strcpy(ext, ".PIC");
  72.  
  73.  fnmerge(fin, drive, dir, file, ext);
  74.  
  75.  /* Check for presence of next parameter */
  76.  
  77.  if(argc == 3)
  78.   {
  79.   fnsplit(argv[2], drive, dir, file, ext);
  80.  
  81.   if(ext[0] == '\0')
  82.    strcpy(ext, ".PCX");
  83.   }
  84.  else
  85.   strcpy(ext, ".PCX");
  86.  
  87.  fnmerge(fout, drive, dir, file, ".PCX");
  88. }
  89.  
  90.  
  91.  
  92. /*
  93.  * mode() - Set the video mode
  94.  */
  95. void mode(WORD mode)
  96. {
  97.  _AH = 0;
  98.  _AL = mode;
  99.  
  100.  geninterrupt(0x10);
  101. }
  102.  
  103.  
  104.  
  105. /*
  106.  * cls() - Clear the screen to the given color
  107.  */
  108. void cls(WORD color)
  109. {
  110.  union REGS r;
  111.  
  112.  
  113.  r.x.ax = 0x0600;
  114.  r.x.cx = 0x0000;
  115.  r.x.dx = 0x184F;
  116.  r.h.bh = color;
  117.  
  118.  int86(0x10, &r, &r);
  119. }
  120.  
  121.  
  122.  
  123. /*
  124.  * get_pixel() - Read a pixel from the BLOAD buffer.
  125.  */
  126. UBYTE get_pixel(UBYTE far *pic, int x, int y)
  127. {
  128.  UBYTE      byte;
  129.  UBYTE far *mem_addr;
  130.  
  131.  
  132.  mem_addr = pic + (y&0x01)*0x2000;
  133.  
  134.  byte = *(mem_addr + ((y & 0xFE)>>1)*0x50 + x/4);
  135.  
  136.  return((byte >> ((3-(x&0x03))<<1))&0x03);
  137. }
  138.  
  139.  
  140.  
  141. /*
  142.  * put_pixel() - Write a pixel to the EGA video buffer
  143.  */
  144. void put_pixel(int x, int y, UBYTE color)
  145. {
  146.  ULONG      off;
  147.  UBYTE far *mem_addr;
  148.  int        dummy, mask;
  149.  
  150.  
  151.  off = (LONG)y * 40L + ((LONG)x / 8L);
  152.  
  153.  mem_addr = (UBYTE far *)(0xA0000000L + off);
  154.  
  155.  mask = 0x80 >> (x % 8);
  156.  
  157.  graph_out(8, mask);
  158.  graph_out(3, 0x00);
  159.  
  160.  seq_out(2, 0x0F);
  161.  
  162.  dummy = *mem_addr;
  163.  
  164.  *mem_addr = 0;
  165.  
  166.  seq_out(2, color);
  167.  
  168.  *mem_addr = 0xFF;
  169.  
  170.  seq_out(2, 0x0F);
  171.  
  172.  graph_out(3, 0x00);
  173.  graph_out(8, 0xFF);
  174. }
  175.  
  176.  
  177.  
  178. /*
  179.  * rd_byte() - Read a byte from the EGA screen, given the address of
  180.  *             the byte and the color plane to read from.
  181.  */
  182. UBYTE rd_byte(ULONG addr, WORD clr_plane)
  183. {
  184.  UBYTE far *mem_addr;
  185.  UBYTE      pixel;
  186.  
  187.  
  188.  mem_addr = (UBYTE far *)(0xA0000000L + addr);
  189.  
  190.  outp(0x3CE, 4);
  191.  outp(0x3CF, clr_plane);
  192.  
  193.  outp(0x3CE, 5);
  194.  outp(0x3CF, 0);
  195.  
  196.  pixel = *mem_addr;
  197.  
  198.  return pixel;
  199. }
  200.  
  201.  
  202.  
  203. /*
  204.  * farload_pic() - Load a BLOAD image into a buffer in RAM.
  205.  *                 Return a pointer to the buffer.
  206.  */
  207. UBYTE far *farload_pic(const char *file_name)
  208. {
  209.  FILE  *fp;
  210.  UBYTE far *buffer, *tbuff;
  211.  ULONG fsize;
  212.  
  213.  
  214.  if((fp = fopen(file_name,"rb")) == NULL)
  215.   {
  216.   printf("\nCan't find %s.\n",file_name);
  217.   return(0);
  218.   }
  219.  
  220.  fsize = filelength(fileno(fp)) - 7;
  221.  
  222.  buffer = (UBYTE far *)farcalloc(fsize, 1);
  223.  
  224.  tbuff  = (UBYTE *)calloc((int)fsize, 1);
  225.  
  226.  fread((void *)tbuff, 1, 7, fp);
  227.  
  228.  fread((void *)tbuff, 1, (int)fsize, fp);
  229.  
  230.  movedata(FP_SEG(tbuff ), FP_OFF(tbuff ),
  231.       FP_SEG(buffer), FP_OFF(buffer), (int)fsize);
  232.  
  233.  fclose(fp);
  234.  
  235.  free((void *)tbuff);
  236.  
  237.  return(buffer);
  238. }
  239.  
  240.  
  241.  
  242. /*
  243.  * save_pcx() - Save the image on EGA page 0 to a .PCX file, using
  244.  *              the default EGA palette
  245.  */
  246. void save_pcx(const char *fname)
  247. {
  248.  FILE  *fp;
  249.  UBYTE  ch, old_ch, red, green, blue;
  250.  int    i, j, k, add1, add2, number, num_out;
  251.  UBYTE  color[16] = {
  252.              0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  253.              0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
  254.             };
  255.  
  256.  
  257.  if((fp = fopen(fname, "wb")) == NULL)
  258.   {
  259.   printf("ERROR:  failure to save %s.PCX\n", fname);
  260.   return;
  261.   }
  262.  
  263.  /* Write out the standard ZSoft .PCX file header:                 */
  264.  
  265.  fputc(0x0A, fp);            /* Byte 0:  0x0A = ZSoft .PCX file    */
  266.  fputc(0x05, fp);            /* Byte 1:  0x05 = PC Paintbrush v3.0 */
  267.  
  268.  fputc(0x01, fp);            /* Byte 2:  0x01 = .PCX RLE coding    */
  269.  fputc(0x01, fp);         /* Byte 3:  number of bits/pixel (1)  */
  270.  
  271.  putw(  0, fp);       /* Bytes  4 -  5:  window left               */
  272.  putw(  0, fp);       /* Bytes  6 -  7:  window top                */
  273.  putw(319, fp);       /* Bytes  8 -  9:  window right              */
  274.  putw(199, fp);          /* Bytes 10 - 11:  window bottom             */
  275.  
  276.  putw(320, fp);       /* Bytes 12 - 13:  Horizontal resolution     */
  277.  putw(200, fp);       /* Bytes 14 - 15:  Vertical resolution       */
  278.  
  279.  ch = 0x00;
  280.  
  281.  /*
  282.   * Bytes 16 - 63:  Color Map.  This consists of 16 consecutive blocks
  283.   *                 of 3 bytes each:  Redbyte, Greenbyte, Bluebyte.
  284.   */
  285.  
  286.  for(i=0 ; i<16 ; i++)
  287.   {
  288.   red   = (((color[i] & 0x20)>>5) | ((color[i] & 0x04)>>1)) * 85;
  289.   green = (((color[i] & 0x10)>>4) |  (color[i] & 0x02)    ) * 85;
  290.   blue  = (((color[i] & 0x08)>>3) | ((color[i] & 0x01)<<1)) * 85;
  291.  
  292.   fputc(red  , fp);
  293.   fputc(green, fp);
  294.   fputc(blue , fp);
  295.   }
  296.  
  297.  fputc(0x00, fp);            /* Byte 64:  Reserved                 */
  298.  fputc(0x04, fp);            /* Byte 65:  Number of planes (4)     */
  299.  
  300.  putw(40, fp);               /* Bytes 66-67:  Bytes per line       */
  301.  
  302.  putw(0x01, fp);             /* Bytes 68-69:  1 = color palette    */
  303.  
  304.  for(i=70 ; i<128 ; i++)     /* Bytes 70 - 127 are unused          */
  305.   fputc(0x00, fp);
  306.  
  307.  for(k=0 ; k<200 ; k++)
  308.   {
  309.   add1   = 40 * k;
  310.   add2   = 0;
  311.   number = 1;
  312.   j      = 0;
  313.   old_ch = rd_byte(add1+(add2++), 0);
  314.  
  315.   for(i=add2 ; i<161 ; i++)
  316.    {
  317.    if(i == 160)
  318.     ch = old_ch-1;
  319.    else
  320.     {
  321.     if(add2 == 40)
  322.      {
  323.      j++;
  324.      add2 = 0;
  325.      }
  326.  
  327.     ch = rd_byte(add1 + add2, j);
  328.     }
  329.  
  330.    if((ch==old_ch) && number<63)
  331.     number++;
  332.    else
  333.     {
  334.     num_out = ((UBYTE)number | 0xC0);
  335.  
  336.     if((number != 1) || ((old_ch&0xC0)==0xC0))
  337.      fputc(num_out, fp);
  338.  
  339.     fputc(old_ch, fp);
  340.  
  341.     old_ch = ch;
  342.     number = 1;
  343.     }
  344.  
  345.    add2++;
  346.    }
  347.   }
  348.  
  349.  fclose(fp);
  350. }
  351.  
  352.  
  353.  
  354.  
  355. /* MAIN */
  356.  
  357. void main(int argc, char *argv[])
  358. {
  359.  int   x, y;
  360.  char  fin[MAXPATH], fout[MAXPATH];
  361.  UBYTE far *picbuf;                       /* image buffer */
  362.  UBYTE ega_color[4] = { 0, 11, 13, 15 };  /* EGA pos for CGA pal 0 */
  363.                
  364.  
  365.  if(argc==1 || argc>3)
  366.   {
  367.   printf("Usage:  bas2pcx <infile> [outfile]\n\n");
  368.   printf("Where:  <infile>  = BLOAD image to load (.PIC extension default)\n");
  369.   printf("        [outfile] = .PCX file generated.  If not specified\n");
  370.   printf("                    input filename is used, with .PCX added.\n");
  371.   exit(0);
  372.   }
  373.  
  374.  get_parms(argc, argv, fin, fout);
  375.  
  376.  if((picbuf = farload_pic(fin)) == NULL)
  377.   exit(-1);
  378.  
  379.  mode(EGA_320_200_16);
  380.  
  381.  for(y=0 ; y<200 ; y++)
  382.   for(x=0 ; x<320 ; x++)
  383.    put_pixel(x, y, ega_color[get_pixel(picbuf, x, y)]);
  384.  
  385.  putch(7);
  386.  
  387.  farfree((void far *)picbuf);
  388.  
  389.  save_pcx(fout);
  390.  
  391.  putch(7);
  392.  
  393.  getch();
  394.  
  395.  mode(0x03);
  396. }
  397.